package cn.madis.ymcc.service.impl;

import cn.madis.ymcc.domain.AlipayInfo;
import cn.madis.ymcc.domain.PayOrder;
import cn.madis.ymcc.dto.Order2PayDto;
import cn.madis.ymcc.dto.PayParamDto;
import cn.madis.ymcc.mapper.PayOrderMapper;
import cn.madis.ymcc.service.IAlipayInfoService;
import cn.madis.ymcc.service.IPayOrderService;
import cn.madis.ymcc.util.AssertUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.common.models.AlipayTradeCloseResponse;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.convert.EntityWriter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Zt
 * @since 2022-08-18
 */
@Service
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {
   @Autowired
   private IAlipayInfoService alipayInfoService;

    /**
     * 此类不能主动报错报错签收失败下次还会消费导致重复消费
     * 保存PayOrder支付单
     * @param order2PayDto
     */
    @Override
    @Transactional
    public void savaPayOrder(Order2PayDto order2PayDto) {
        String orderNo = order2PayDto.getOrderNo();
        EntityWrapper<PayOrder> wrapper = new EntityWrapper<>();
        wrapper.eq("order_no",orderNo);
        PayOrder payOrder = selectOne(wrapper);
        if (payOrder == null){
            payOrder = new PayOrder();
            BeanUtils.copyProperties(order2PayDto,payOrder);
            payOrder.setCreateTime(new Date());
            payOrder.setPayStatus(PayOrder.STATE_UNPAID);
            insert(payOrder);
        }
    }

    /**
     * 根据orderNo看有否支付单
     * @param orderNo
     */
    @Override
    public PayOrder checkPayOrder(String orderNo) {
        EntityWrapper<PayOrder> wrapper = new EntityWrapper<>();
        wrapper.eq("order_no",orderNo);
        return  selectOne(wrapper);
    }

    /**
     * 发起支付
     * @param payParamDto
     */
    @Override
    public String apply(PayParamDto payParamDto) {
    //业务参数校验
        //支付单存在与否
        PayOrder payOrder = checkPayOrder(payParamDto.getOrderNo());
        AssertUtil.isNotNull(payOrder,"支付订单不存在");
        //支付单状态是否待支付
        boolean b = payOrder.getPayStatus() == PayOrder.STATE_UNPAID;
        AssertUtil.isTrue(b,"订单状态错误");
        //支付方式
        int payType = payOrder.getPayType().intValue();
        if (payType == 1){
           return pay(payOrder,payParamDto);
        }else if (payType == 2){

        }else if (payType == 0){

        }
        return null;
    }



    public  String pay(PayOrder payOrder,PayParamDto payParamDto){
        AlipayInfo alipayInfo = alipayInfoService.selectList(null).get(0);
        // 1. 设置参数（全局只需设置一次）
        Factory.setOptions(getOptions(alipayInfo));
        try {

            AlipayTradePagePayResponse response = Factory.Payment.Page().pay(
                    payOrder.getSubject(),
                    payOrder.getOrderNo(),
                    payOrder.getAmount().toString(),
                    //回调地址
                    StringUtils.isEmpty(payParamDto.getCallUrl())?alipayInfo.getReturnUrl():payParamDto.getCallUrl()

            );
           /* // 2. 发起API调用（以创建当面付收款二维码为例）
            AlipayTradePrecreateResponse response = Payment.FaceToFace()
                    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");*/
            // 3. 处理响应或异常
            if (ResponseChecker.success(response)) {
                System.out.println(response.getBody());
                System.out.println("调用成功");
                return response.getBody();
            } else {
                System.err.println("调用失败，原因：" + response);
            }
        } catch (Exception e) {
            System.err.println("调用遭遇异常，原因：" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return null;
    }
    private  Config getOptions(AlipayInfo alipayInfo) {
        Config config = new Config();
        config.protocol = alipayInfo.getProtocol();
        config.gatewayHost = alipayInfo.getGatewayHost();
        config.signType = alipayInfo.getSignType();
        config.appId = alipayInfo.getAppId();   //"<-- 请填写您的AppId，例如：2019091767145019 -->";
        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        // "<-- 请填写您的应用私钥，例如：MIIEvQIBADANB ... ... -->"
        config.merchantPrivateKey = alipayInfo.getMerchantPrivateKey();
        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
        //"<-- 请填写您的支付宝公钥，例如：MIIBIjANBg... -->"
        config.alipayPublicKey =alipayInfo.getAlipayPublicKey() ;
        //可设置异步通知接收服务地址（可选）
        config.notifyUrl = alipayInfo.getNotifyUrl();

        return config;
    }


    /**
     * 支付超时取消支付单逻辑
     * @param orderNo
     */
    @Override
    public void payTimeOutCancelPayOrder(String orderNo) {
        PayOrder payOrder = checkPayOrder(orderNo);
        boolean b = payOrder.getPayStatus() == PayOrder.STATE_UNPAID;
        if (!b){
            return;
        }
        payOrder.setPayStatus(PayOrder.STATE_CANCEL);
        payOrder.setUpdateTime(new Date());
        updateById(payOrder);
        //调用支付宝关闭交易
        try {
            Factory.Payment.Common().close(orderNo);
            //关闭成功
            //关闭失败走notify退款
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
